package com.jesper.seckill.dao;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jesper.seckill.entity.po.GoodsSeckill;
import com.jesper.seckill.mapper.GoodsSeckillMapper;
import org.springframework.stereotype.Service;

@Service
public class GoodsSeckillDao extends ServiceImpl<GoodsSeckillMapper, GoodsSeckill> {

    /**
     * 减少库存，每次减一 (最重试5次)
     */
    public void reduceStock(Long goodsId){
        if (goodsId == null){
            return;
        }
        int safeNum = 0;
        boolean continueFlag = true;
        do {
            this.updateGoodsSeckillStockCount(goodsId);
            continueFlag = false;
        } while (continueFlag && safeNum++ < 5);
    }

    /**
     * stock_count > 0 和 版本号实现乐观锁 防止超卖
     */
    public void  updateGoodsSeckillStockCount(Long goodsId){
        if (goodsId == null){
            return;
        }
        lambdaUpdate()
                .eq(GoodsSeckill::getGoodsId,goodsId)
                .eq(GoodsSeckill::getVersion,this.getLatestVersionByGoodsId(goodsId))
                .gt(GoodsSeckill::getStockCount,0)
                .setSql("stock_count = stock_count - 1, version= version + 1")
                .update();
    }

    /**
     * 根据商品id获取最新版本号(默认为0)
     */
    public Integer getLatestVersionByGoodsId(Long goodsId){
        if (goodsId == null){
            return 0;
        }
        GoodsSeckill seckill = lambdaQuery()
                .eq(GoodsSeckill::getGoodsId,goodsId)
                .select(GoodsSeckill::getVersion)
                .one();
        if (seckill == null){
            return 0;
        }
        return seckill.getVersion();
    }
}
